package org.grayrabbit.cloud.core.config;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public abstract class Configurator {
	private ConcurrentMap<String, ConcurrentMap<String, ConcurrentMap<String, String>>> properties;

	protected Configurator() {
		this.properties = new ConcurrentHashMap<String, ConcurrentMap<String, ConcurrentMap<String, String>>>();
	}

	protected abstract String read(String category, String name, String property)
			throws ConfiguratorException;

	public String getProperty(String category, String name, String property)
			throws ConfiguratorException {
		assert (category != null);
		assert (property != null);

		ConcurrentMap<String, ConcurrentMap<String, String>> ctg = this.properties
				.get(category);
		if (ctg == null) {
			ctg = new ConcurrentHashMap<String, ConcurrentMap<String, String>>();
			this.properties.putIfAbsent(category, ctg);
			ctg = this.properties.get(category);
		}

		String module = name;
		if (module == null)
			module = category;
		ConcurrentMap<String, String> prop = ctg.get(module);
		if (prop == null) {
			prop = new ConcurrentHashMap<String, String>();
			ctg.putIfAbsent(module, prop);
			prop = ctg.get(module);
		}

		String value = (String) prop.get(property);
		if (value == null) {
			value = read(category, name, property);
			if (value != null) {
				prop.putIfAbsent(property, value);
			}
		}

		return value;
	}
}
